class JsonFlat {

    constructor(jquery) {
        if (jquery) {
            this.jquery = jquery;
        } else {
            this.jquery = $;
        }
    }

    /**
     * 将JSON转换为Dict
     * @param json
     */
    toDict(json) {
        let data = {};
        this.#_deFoldObject(json, data, "");
        return data;
    }

    #_deFoldObject(json, data, key) {
        let self = this;
        if (key) key += ".";
        if (json instanceof Object) {
            Object.keys(json).forEach(function (k, idx) {
                let subKey = key + k;
                let val = json[k];
                if (val instanceof Array) {
                    self.#_deFoldArray(val, data, subKey);
                } else if (typeof val === 'object') {
                    self.#_deFoldObject(val, data, subKey);
                } else {
                    data[subKey] = val;
                }
            });
        }
    }

    #_deFoldArray(arr, data, key) {
        let self = this;
        if (arr instanceof Array) {
            arr.forEach(function (val, idx) {
                let subKey = key + "[" + idx + "]";
                if (val instanceof Array) {
                    self.#_deFoldArray(val, data, subKey);
                } else if (typeof val === 'object') {
                    self.#_deFoldObject(val, data, subKey);
                } else {
                    data[subKey] = val;
                }
            });
        }
    }

    /**
     * 将Dict还原为Json
     * @param dict
     * @return {{}}
     */
    toJson(dict) {
        if (this.jquery) {
            let json = {};
            this.#_beFold(dict, json);
            return json;
        }
        throw "Need Jquery Model";
    }

    #_beFold(obj, json) {
        let self = this;
        if (obj instanceof Object) {
            Object.keys(obj).forEach(function (key, idx) {
                self.jquery.extend(true, json, self.#_makeObjectByKey(key, obj[key]))
            });
        }
    }

    #_makeObjectByKey(key, val) {
        let self = this;
        let arrayFlagPatter = /\[(\d+)]/i
        let arrayFlagSeat = key.search(arrayFlagPatter)
        let objectFlagSeat = key.indexOf(".");
        let obj = {};
        if (arrayFlagSeat === objectFlagSeat) {
            obj[key] = val;
        } else if (arrayFlagSeat !== -1 && (arrayFlagSeat < objectFlagSeat || objectFlagSeat === -1)) {
            let arrayFlagInfo = key.match(arrayFlagPatter);
            let arrayFlag = arrayFlagInfo[0];
            let arrayIdx = parseInt(arrayFlagInfo[1]);
            let firstKey = key.substring(0, arrayFlagSeat);
            let lastKey = key.substring(arrayFlagSeat).replace(arrayFlag, "");
            if (firstKey && lastKey) {
                let subArr = [];
                subArr[arrayIdx] = self.#_makeObjectByKey(lastKey, val);
                obj[firstKey] = subArr;
            } else if (firstKey) {
                let subArr = [];
                subArr[arrayIdx] = val;
                obj[firstKey] = subArr;
            } else if (lastKey) {
                obj = [];
                obj[arrayIdx] = self.#_makeObjectByKey(lastKey, val);
            } else {
                obj = [];
                obj[arrayIdx] = val;
            }
        } else if (objectFlagSeat !== -1) {
            let firstKey = key.substring(0, objectFlagSeat);
            let lastKey = key.substring(objectFlagSeat + 1);
            if (firstKey && lastKey) {
                obj[firstKey] = self.#_makeObjectByKey(lastKey, val);
            } else if (firstKey) {
                obj[firstKey] = val;
            } else if (lastKey) {
                return self.#_makeObjectByKey(lastKey, val);
            } else {
                return val;
            }
        }
        return obj;
    }
}